package com.efrei.schoolmanager.views;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Set;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.SwingUtilities;
import javax.swing.text.MaskFormatter;

import org.hibernate.HibernateException;

import com.efrei.schoolmanager.controlers.ControleurEleve;
import com.efrei.schoolmanager.exceptions.LogicException;
import com.efrei.schoolmanager.model.obj.Classe;
import com.efrei.schoolmanager.model.obj.Eleve;
import com.efrei.schoolmanager.model.obj.Etablissement;
import com.efrei.schoolmanager.model.obj.Medecin;
import com.efrei.schoolmanager.model.obj.Pays;
import com.efrei.schoolmanager.model.obj.Responsable;
import com.efrei.schoolmanager.model.obj.Ville;
import com.efrei.schoolmanager.tools.Tools;
import com.efrei.schoolmanager.views.components.CustomButton;
import com.efrei.schoolmanager.views.components.CustomFormattedTextField;
import com.efrei.schoolmanager.views.components.CustomTextArea;
import com.efrei.schoolmanager.views.components.CustomTextField;

public abstract class VueEditionEleve extends JPanel {
	private static final long serialVersionUID = 8375396416239909335L;

	private final VueGenerale vueParente;
	// Notre instance de notre objet controleur
	private final ControleurEleve controleur;

	/* Panels principaux */
	private JPanel centerPanel, validationPanel, northPanel, mainPanel;
	/* Sous panels */
	private JPanel infosElevePanel, elevePanel, medecinPanel,
			dossierMedicalPanel, responsablesClassePanel,
			etablissementPrecPanel;
	/* Labels */
	private JLabel titleLabel, prenomEleveLabel, nomEleveLabel,
			nationaliteEleveLabel, dateInscriptionEleveLabel,
			matriculeEleveLabel, photoEleveLabel, lieuNaissanceEleveLabel,
			dateNaissanceEleveLabel, villeNaissanceEleveLabel,
			codePostalNaissanceEleveLabel, paysNaissanceEleveLabel,
			etablissementPrecLabel, nomEtablissementPrecLabel,
			rueEtablissementPrecLabel, villeEtablissementPrecLabel,
			codePostalEtablissementPrecLabel, paysEtablissementPrecLabel,
			telEtablissementPrecLabel, coordonneesEleveLabel, rueEleveLabel,
			villeEleveLabel, codePostalEleveLabel, paysEleveLabel,
			emailEleveLabel, telFixeEleveLabel, telMobileEleve1Label,
			telMobileEleve2Label, allergiesLabel, vaccinsLabel,
			rmqMedicalesLabel, prenomMedecinLabel, nomMedecinLabel,
			rueMedecinLabel, villeMedecinLabel, codePostalMedecinLabel,
			paysMedecinLabel, emailMedecinLabel, telephoneMedecinLabel;
	/* Zones de textes mono-ligne */
	private CustomTextField prenomEleveTextField, nomEleveTextField,
			matriculeEleveTextField, photoEleveTextField,
			villeNaissanceEleveTextField, nomEtablissementPrecTextField,
			rueEtablissementPrecTextField, villeEtablissementPrecTextField,
			rueEleveTextField, villeEleveTextField, emailEleveTextField,
			prenomMedecinTextField, nomMedecinTextField, rueMedecinTextField,
			villeMedecinTextField, emailMedecinTextField;
	private CustomFormattedTextField dateInscriptionEleveTextField,
			dateNaissanceEleveTextField, codePostalNaissanceEleveTextField,
			codePostalEtablissementPrecTextField,
			telEtablissementPrecTextField, codePostalEleveTextField,
			telFixeEleveTextField, telMobileEleve1TextField,
			telMobileEleve2TextField, codePostalMedecinTextField,
			telephoneMedecinTextField;
	/* Zones de textes multi-lignes */
	private CustomTextArea allergiesTextArea, vaccinsTextArea,
			rmqMedicalesTextArea;
	/* Boutons */
	private CustomButton ajouterResponsableButton, editerResponsableButton,
			supprimerResponsableButton, editerMedecinButton,
			ajouterMedecinButton, ajouterEleveButton,
			ajouterEtablissementPrecButton, editerEtablissementPrecButton;
	/* Listes déroulantes */
	private JComboBox nationaliteEleveComboBox, paysNaissanceEleveComboBox,
			paysEtablissementPrecComboBox, paysEleveComboBox,
			responsablesComboBox, classesComboBox, medecinsTraitantComboBox,
			paysMedecinComboBox, etablissementsComboBox;

	/* Radio boutons */
	private JRadioButton sexeMRadioButton, sexeFRadioButton;
	private ButtonGroup sexeButtonGroup;

	private boolean infoMedecinVisible = false;
	private boolean infoEtablissementVisible = false;

	private boolean editerEtablissementInProgress = false;
	private boolean editerMedecinInProgress = false;

	private boolean infoMedecinEnabled;
	private boolean infoEtablissementEnabled;

	public VueEditionEleve(final VueGenerale vueParente,
			final ControleurEleve controleur) {
		super();
		this.vueParente = vueParente;
		this.controleur = controleur;

		new Thread(new Runnable() {
			@Override
			public void run() {
				boolean error = false;
				try {
					/* Composants */
					initLabels();
					initTextFields();
					initTextAreas();
					initButtons();
					initComboBox();
					initRadioButtons();
					initMainPanels();
					remplirNorthPanel();

					/* Panel principal */
					initContentPane();
					remplirEtablissementPrecPanel();
					remplirValidationPanel();
					remplirInfoElevePanel();
					remplirResponsablesClassePanel();
					remplirDossierMedicalPanel();
					remplirElevePanel();
					remplirMedecinPanel();
					remplirMainPanel();

					// Si l'eleve n'est pas nouveau, il a des infos a afficher
					if (!controleur.isNew())
						updateEleveInfos();

					/* Frame */
					configurerVue();
					afficherInfosMedecins(false, false);
					afficherInfosEtablissements(false, false);
					setVisible(true);
				} catch (final Exception e) {
					// en cas d'erreur, on efface tout
					error = true;
					SwingUtilities.invokeLater(new Runnable() {
						@Override
						public void run() {
							vueParente.displayError(e);
							vueParente.removePanel();
							vueParente.stopBarreChargement();
						}
					});
				}
				if (!error)
					SwingUtilities.invokeLater(new Runnable() {
						@Override
						public void run() {
							vueParente.stopBarreChargement();
						}
					});
			}
		}).start();
		vueParente.startBarreChargement();
	}

	/**
	 * Met à jour les champs avec les informations de l'eleve
	 */
	private void updateEleveInfos() {
		Eleve eleveCourant = controleur.getEleve();

		Pays nationalite = eleveCourant.getNationalite();
		Ville ville = eleveCourant.getVille();
		Ville villeNaissance = eleveCourant.getVilleNaissance();
		Etablissement etablissementPrecedent = eleveCourant
				.getEtablissementPrecedent();
		Medecin medecinTraitant = eleveCourant.getMedecinTraitant();
		Set<Classe> classes = eleveCourant.getMostRecentClasses();

		prenomEleveTextField.setText(eleveCourant.getPrenom());
		nomEleveTextField.setText(eleveCourant.getNom());
		matriculeEleveTextField.setText(eleveCourant.getMatricule());
		photoEleveTextField.setText(eleveCourant.getPhoto());
		rueEleveTextField.setText(eleveCourant.getRue());
		emailEleveTextField.setText(eleveCourant.getEmail());
		telFixeEleveTextField.setText(eleveCourant.getTelDomicile());
		telMobileEleve1TextField.setText(eleveCourant.getTelMobile1());
		telMobileEleve2TextField.setText(eleveCourant.getTelMobile2());
		if (eleveCourant.getSexe().equals(Eleve.HOMME))
			sexeMRadioButton.setSelected(true);
		else
			sexeFRadioButton.setSelected(true);
		dateInscriptionEleveTextField.setText(Tools.dateToString(
				eleveCourant.getDateInscription(), Tools.SEPARATEUR_FR));
		dateNaissanceEleveTextField.setText(Tools.dateToString(
				eleveCourant.getDateNaissance(), Tools.SEPARATEUR_FR));

		// Ajout des champs et mise à jour des combobox si info disponible
		if (nationalite != null) {
			nationaliteEleveComboBox.setSelectedItem(nationalite);
		}
		if (ville != null) {
			villeEleveTextField.setText(ville.getNom());
			codePostalEleveTextField.setText(ville.getCodePostal());
			paysEleveComboBox.setSelectedItem(villeNaissance.getPays());
		}
		if (etablissementPrecedent != null) {
			nomEtablissementPrecTextField.setText(etablissementPrecedent
					.getNom());
			rueEtablissementPrecTextField.setText(etablissementPrecedent
					.getRue());
			villeEtablissementPrecTextField.setText(etablissementPrecedent
					.getVille().getNom());
			codePostalEtablissementPrecTextField.setText(etablissementPrecedent
					.getVille().getCodePostal());
			etablissementsComboBox.setSelectedItem(etablissementPrecedent);
		}
		if (villeNaissance != null) {
			villeNaissanceEleveTextField.setText(villeNaissance.getNom());
			codePostalNaissanceEleveTextField.setText(villeNaissance
					.getCodePostal());
			paysNaissanceEleveComboBox
					.setSelectedItem(villeNaissance.getPays());
		}
		if (medecinTraitant != null) {
			medecinsTraitantComboBox.setSelectedItem(medecinTraitant);
		}
		if (classes != null && classes.size() > 0) {
			for (Classe classe : classes) {
				classesComboBox.setSelectedItem(classe);
			}
		}
	}

	private void afficherInfosMedecins(boolean isVisible, boolean isEnabled) {
		prenomMedecinLabel.setVisible(isVisible);
		prenomMedecinTextField.setVisible(isVisible);
		nomMedecinLabel.setVisible(isVisible);
		nomMedecinTextField.setVisible(isVisible);
		telephoneMedecinLabel.setVisible(isVisible);
		telephoneMedecinTextField.setVisible(isVisible);
		emailMedecinLabel.setVisible(isVisible);
		emailMedecinTextField.setVisible(isVisible);
		rueMedecinLabel.setVisible(isVisible);
		rueMedecinTextField.setVisible(isVisible);
		villeMedecinLabel.setVisible(isVisible);
		villeMedecinTextField.setVisible(isVisible);
		codePostalMedecinLabel.setVisible(isVisible);
		codePostalMedecinTextField.setVisible(isVisible);
		paysMedecinLabel.setVisible(isVisible);
		paysMedecinComboBox.setVisible(isVisible);

		prenomMedecinLabel.setEnabled(isEnabled);
		prenomMedecinTextField.setEnabled(isEnabled);
		nomMedecinLabel.setEnabled(isEnabled);
		nomMedecinTextField.setEnabled(isEnabled);
		telephoneMedecinLabel.setEnabled(isEnabled);
		telephoneMedecinTextField.setEnabled(isEnabled);
		emailMedecinLabel.setEnabled(isEnabled);
		emailMedecinTextField.setEnabled(isEnabled);
		rueMedecinLabel.setEnabled(isEnabled);
		rueMedecinTextField.setEnabled(isEnabled);
		villeMedecinLabel.setEnabled(isEnabled);
		villeMedecinTextField.setEnabled(isEnabled);
		codePostalMedecinLabel.setEnabled(isEnabled);
		codePostalMedecinTextField.setEnabled(isEnabled);
		paysMedecinLabel.setEnabled(isEnabled);
		paysMedecinComboBox.setEnabled(isEnabled);

		infoMedecinVisible = isVisible;
		infoMedecinEnabled = isEnabled;
	}

	private void afficherInfosEtablissements(boolean isVisible,
			boolean isEnabled) {
		// Affiche/Cache les infos de l'etablissement
		nomEtablissementPrecLabel.setVisible(isVisible);
		nomEtablissementPrecTextField.setVisible(isVisible);
		rueEtablissementPrecLabel.setVisible(isVisible);
		rueEtablissementPrecTextField.setVisible(isVisible);
		villeEtablissementPrecLabel.setVisible(isVisible);
		villeEtablissementPrecTextField.setVisible(isVisible);
		codePostalEtablissementPrecLabel.setVisible(isVisible);
		codePostalEtablissementPrecTextField.setVisible(isVisible);
		paysEtablissementPrecLabel.setVisible(isVisible);
		paysEtablissementPrecComboBox.setVisible(isVisible);
		telEtablissementPrecLabel.setVisible(isVisible);
		telEtablissementPrecTextField.setVisible(isVisible);

		// Grise/Degrise les infos de l'etablissement
		nomEtablissementPrecLabel.setEnabled(isEnabled);
		nomEtablissementPrecTextField.setEnabled(isEnabled);
		rueEtablissementPrecLabel.setEnabled(isEnabled);
		rueEtablissementPrecTextField.setEnabled(isEnabled);
		villeEtablissementPrecLabel.setEnabled(isEnabled);
		villeEtablissementPrecTextField.setEnabled(isEnabled);
		codePostalEtablissementPrecLabel.setEnabled(isEnabled);
		codePostalEtablissementPrecTextField.setEnabled(isEnabled);
		paysEtablissementPrecLabel.setEnabled(isEnabled);
		paysEtablissementPrecComboBox.setEnabled(isEnabled);
		telEtablissementPrecLabel.setEnabled(isEnabled);
		telEtablissementPrecTextField.setEnabled(isEnabled);

		infoEtablissementVisible = isVisible;
		infoEtablissementEnabled = isEnabled;
	}

	private void resetInfoMedecin() {
		prenomMedecinTextField.setText("");
		nomMedecinTextField.setText("");
		telephoneMedecinTextField.setText("");
		emailMedecinTextField.setText("");
		rueMedecinTextField.setText("");
		villeMedecinTextField.setText("");
		codePostalMedecinTextField.setText("");
		paysMedecinComboBox.setSelectedIndex(0);
	}

	private void resetInfoEtablissement() {
		paysEtablissementPrecComboBox.setSelectedIndex(0);
		nomEtablissementPrecTextField.setText("");
		rueEtablissementPrecTextField.setText("");
		villeEtablissementPrecTextField.setText("");
		codePostalEtablissementPrecTextField.setText("");
		telEtablissementPrecTextField.setText("");
	}

	private void configurerVue() {
		// Permet redimensionnement de l'écran
		Dimension preferedSize = getPreferredSize();
		Dimension dimensionIdeale = new Dimension(preferedSize.width,
				preferedSize.height + 28);
		setMinimumSize(dimensionIdeale);
		setSize(dimensionIdeale);
		setVisible(true);
	}

	private void initContentPane() {
		setLayout(new BorderLayout());
		add(centerPanel, BorderLayout.CENTER);
		add(northPanel, BorderLayout.NORTH);
	}

	private void initMainPanels() {
		/* Panel au centre de la fenetre */
		centerPanel = new JPanel();
		mainPanel = new JPanel();
		centerPanel.add(mainPanel);
	}

	private void initLabels() {
		titleLabel = new JLabel(getTitle());
		titleLabel.setFont(new Font("Arial", Font.BOLD, 20));
		prenomEleveLabel = new JLabel("Prénom:");
		nomEleveLabel = new JLabel("Nom:");
		nationaliteEleveLabel = new JLabel("Nationalité");
		dateInscriptionEleveLabel = new JLabel("Inscrit le: (jj/mm/aaaa)");
		matriculeEleveLabel = new JLabel("Matricule:");
		photoEleveLabel = new JLabel("URL de la photo:");
		lieuNaissanceEleveLabel = new JLabel("Lieu de naissance");
		lieuNaissanceEleveLabel.setFont(new Font("Arial", Font.ITALIC, 13));
		dateNaissanceEleveLabel = new JLabel("Né le: (jj/mm/aaaa)");
		villeNaissanceEleveLabel = new JLabel("à");
		codePostalNaissanceEleveLabel = new JLabel("Code postal:");
		paysNaissanceEleveLabel = new JLabel("Pays:");
		etablissementPrecLabel = new JLabel("Etablissement précedant");
		etablissementPrecLabel.setFont(new Font("Arial", Font.ITALIC, 13));
		nomEtablissementPrecLabel = new JLabel("Nom de l'établissement:");
		rueEtablissementPrecLabel = new JLabel("Rue:");
		villeEtablissementPrecLabel = new JLabel("Ville:");
		codePostalEtablissementPrecLabel = new JLabel("Code postal");
		paysEtablissementPrecLabel = new JLabel("Pays:");
		telEtablissementPrecLabel = new JLabel("Télephone:");
		coordonneesEleveLabel = new JLabel("Coordonnées de l'élève");
		coordonneesEleveLabel.setFont(new Font("Arial", Font.ITALIC, 13));
		rueEleveLabel = new JLabel("Rue:");
		villeEleveLabel = new JLabel("Ville:");
		codePostalEleveLabel = new JLabel("Code postal:");
		paysEleveLabel = new JLabel("Pays");
		emailEleveLabel = new JLabel("E-mail:");
		telFixeEleveLabel = new JLabel("Télephone fixe:");
		telMobileEleve1Label = new JLabel("Télephone mobile 1:");
		telMobileEleve2Label = new JLabel("Télephone mobile 2:");
		allergiesLabel = new JLabel("Allergies:");
		vaccinsLabel = new JLabel("Vaccins:");
		rmqMedicalesLabel = new JLabel("Remarques médicales:");
		prenomMedecinLabel = new JLabel("Prénom:");
		nomMedecinLabel = new JLabel("Nom:");
		rueMedecinLabel = new JLabel("Rue:");
		villeMedecinLabel = new JLabel("Ville:");
		codePostalMedecinLabel = new JLabel("Code postal:");
		paysMedecinLabel = new JLabel("Pays:");
		emailMedecinLabel = new JLabel("E-mail:");
		telephoneMedecinLabel = new JLabel("Télephone:");
	}

	private void initTextFields() {
		/* Text fields */
		prenomEleveTextField = new CustomTextField("");
		nomEleveTextField = new CustomTextField("");
		matriculeEleveTextField = new CustomTextField("");
		photoEleveTextField = new CustomTextField("");
		photoEleveTextField = new CustomTextField("", new Dimension(250, 20));
		villeNaissanceEleveTextField = new CustomTextField("");
		nomEtablissementPrecTextField = new CustomTextField("");
		rueEtablissementPrecTextField = new CustomTextField("");
		villeEtablissementPrecTextField = new CustomTextField("");
		rueEleveTextField = new CustomTextField("");
		villeEleveTextField = new CustomTextField("");
		emailEleveTextField = new CustomTextField("");
		prenomMedecinTextField = new CustomTextField("");
		nomMedecinTextField = new CustomTextField("");
		rueMedecinTextField = new CustomTextField("");
		villeMedecinTextField = new CustomTextField("");
		emailMedecinTextField = new CustomTextField("");
		/* Formated text fields */
		// Dates
		dateInscriptionEleveTextField = new CustomFormattedTextField(
				new SimpleDateFormat("dd/MM/yyyy"));
		dateNaissanceEleveTextField = new CustomFormattedTextField(
				new SimpleDateFormat("dd/MM/yyyy"));
		try {
			// Code postal d'exactement cinq chiffres
			MaskFormatter codePostalMask = new MaskFormatter("#####");
			// Numéro de télephone d'exactement dix chiffres
			MaskFormatter telephoneMask = new MaskFormatter("##########");
			// Codes postaux
			codePostalNaissanceEleveTextField = new CustomFormattedTextField(
					codePostalMask);
			codePostalEtablissementPrecTextField = new CustomFormattedTextField(
					codePostalMask);
			codePostalEleveTextField = new CustomFormattedTextField(
					codePostalMask);
			codePostalMedecinTextField = new CustomFormattedTextField(
					codePostalMask);
			// Télephones
			telEtablissementPrecTextField = new CustomFormattedTextField(
					telephoneMask);
			telFixeEleveTextField = new CustomFormattedTextField(telephoneMask);
			telMobileEleve1TextField = new CustomFormattedTextField(
					telephoneMask);
			telMobileEleve2TextField = new CustomFormattedTextField(
					telephoneMask);
			telephoneMedecinTextField = new CustomFormattedTextField(
					telephoneMask);
		} catch (ParseException e) {
			e.printStackTrace();
		}

	}

	private void initTextAreas() {
		allergiesTextArea = new CustomTextArea();
		vaccinsTextArea = new CustomTextArea();
		rmqMedicalesTextArea = new CustomTextArea();
	}

	private void initButtons() {
		/* Listeners */
		EditerEleveButtonListener ajouterEleveListener = new EditerEleveButtonListener();
		AjouterResponsableButtonListener ajouterResponsableListener = new AjouterResponsableButtonListener();
		AjouterMedecinButtonListener ajouterMedecinListener = new AjouterMedecinButtonListener();
		EditerResponsableButtonListener editerResponsableListener = new EditerResponsableButtonListener();
		SupprimerResponsableButtonListener supprimerResponsableListener = new SupprimerResponsableButtonListener();
		EditerMedecinButtonListener editerMedecinListener = new EditerMedecinButtonListener();
		AjouterEtablissementPrecButtonListener ajouterEtablissementListener = new AjouterEtablissementPrecButtonListener();
		EditerEtablissementPrecButtonListener editerEtablissementListener = new EditerEtablissementPrecButtonListener();
		ajouterResponsableButton = new CustomButton("Nouveau responsable");
		ajouterResponsableButton.addActionListener(ajouterResponsableListener);
		editerResponsableButton = new CustomButton("Editer responsable");
		editerResponsableButton.addActionListener(editerResponsableListener);
		supprimerResponsableButton = new CustomButton("Supprimer responsable ");
		supprimerResponsableButton
				.addActionListener(supprimerResponsableListener);
		editerMedecinButton = new CustomButton("Editer médecin");
		editerMedecinButton.addActionListener(editerMedecinListener);
		ajouterMedecinButton = new CustomButton("Ajouter médecin");
		ajouterMedecinButton.addActionListener(ajouterMedecinListener);
		ajouterEleveButton = new CustomButton(getEditionBoutonText());
		ajouterEleveButton.addActionListener(ajouterEleveListener);
		ajouterEtablissementPrecButton = new CustomButton(
				"Ajouter etablissement");
		ajouterEtablissementPrecButton
				.addActionListener(ajouterEtablissementListener);
		editerEtablissementPrecButton = new CustomButton("Editer etablissement");
		editerEtablissementPrecButton
				.addActionListener(editerEtablissementListener);
		editerEtablissementPrecButton.setEnabled(false);
	}

	private void initComboBox() {
		/* Listeners */
		MedecinsTraitantComboBoxListener medecinsTraitantListener = new MedecinsTraitantComboBoxListener();
		EtablissementsComboBoxListener etablissementsListener = new EtablissementsComboBoxListener();

		/* Combobox */
		// Pays de naissance de l'eleve
		paysNaissanceEleveComboBox = new JComboBox();

		// Pays de l'eleve
		paysEleveComboBox = new JComboBox();

		// Nationalite de l'eleve
		nationaliteEleveComboBox = new JComboBox();

		// Pays de l'etablissement precendent
		paysEtablissementPrecComboBox = new JComboBox();

		// Responsables
		responsablesComboBox = new JComboBox();

		// Classes
		classesComboBox = new JComboBox();

		// Medecins
		medecinsTraitantComboBox = new JComboBox();
		medecinsTraitantComboBox.addActionListener(medecinsTraitantListener);

		// Pays du medecin traitant
		paysMedecinComboBox = new JComboBox();

		// Etablissements
		etablissementsComboBox = new JComboBox();
		etablissementsComboBox.addActionListener(etablissementsListener);

		// Liste de pays
		List<Pays> listPays = null;
		try {
			listPays = controleur.getPays();
		} catch (HibernateException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

		if (listPays != null) {
			// Remplissage pour toutes les combobox de pays
			paysNaissanceEleveComboBox.addItem("--Selectionnez un pays--");
			paysEleveComboBox.addItem("--Selectionnez une nationalite--");
			nationaliteEleveComboBox
					.addItem("--Selectionnez une nationalite--");
			paysEtablissementPrecComboBox
					.addItem("--Selectionnez une nationalite--");
			paysMedecinComboBox.addItem("--Selectionnez un pays--");
			for (Pays pays : listPays) {
				paysNaissanceEleveComboBox.addItem(pays);
				paysEleveComboBox.addItem(pays);
				nationaliteEleveComboBox.addItem(pays);
				paysEtablissementPrecComboBox.addItem(pays);
				paysMedecinComboBox.addItem(pays);
			}
		}

		// Ajouter les classes
		classesComboBox.addItem("--Sélectionnez une classe--");
		try {
			for (Classe classe : controleur.getClasses()) {
				classesComboBox.addItem(classe);
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

		// Ajouter les medecins
		medecinsTraitantComboBox.addItem("--Selectionnez du medecin--");
		try {
			for (Medecin medecin : controleur.getMedecins()) {
				medecinsTraitantComboBox.addItem(medecin);
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

		// Ajouter les responsables de l'eleve
		responsablesComboBox.addItem("--Editer/Supprimer un responsable--");
		try {
			for (Responsable responsable : controleur.getResponsables()) {
				responsablesComboBox.addItem(responsable);
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

		// Ajouter les etablissements
		etablissementsComboBox.addItem("--Selectionnez un etablissement--");
		try {
			for (Etablissement etablissement : controleur.getEtablissements()) {
				etablissementsComboBox.addItem(etablissement);
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void initRadioButtons() {
		sexeMRadioButton = new JRadioButton("Homme");
		sexeFRadioButton = new JRadioButton("Femme");
		sexeButtonGroup = new ButtonGroup();
		sexeButtonGroup.add(sexeMRadioButton);
		sexeButtonGroup.add(sexeFRadioButton);
	}

	private void remplirEtablissementPrecPanel() {
		etablissementPrecPanel = new JPanel();
		GroupLayout gl = new GroupLayout(etablissementPrecPanel);
		etablissementPrecPanel.setLayout(gl);
		// Espacement des composants
		gl.setAutoCreateGaps(true);
		// Espacement entre composants et conteneur
		gl.setAutoCreateContainerGaps(true);

		// Groupe sequentiel sur l'axe horizontal
		GroupLayout.SequentialGroup hGroup = gl.createSequentialGroup();

		// Constitution des groupes paralleles horizontalement
		/* 1e colonne */
		hGroup.addGroup(gl.createParallelGroup()
				.addComponent(etablissementPrecLabel)
				.addComponent(etablissementsComboBox)
				.addComponent(nomEtablissementPrecLabel)
				.addComponent(villeEtablissementPrecLabel)
				.addComponent(paysEtablissementPrecLabel));
		/* 2e colonne */
		hGroup.addGroup(gl.createParallelGroup()
				.addComponent(ajouterEtablissementPrecButton)
				.addComponent(nomEtablissementPrecTextField)
				.addComponent(villeEtablissementPrecTextField)
				.addComponent(paysEtablissementPrecComboBox));
		/* 3e colonne */
		hGroup.addGroup(gl.createParallelGroup()
				.addComponent(editerEtablissementPrecButton)
				.addComponent(rueEtablissementPrecLabel)
				.addComponent(codePostalEtablissementPrecLabel)
				.addComponent(telEtablissementPrecLabel));
		/* 4e colonne */
		hGroup.addGroup(gl.createParallelGroup()
				.addComponent(rueEtablissementPrecTextField)
				.addComponent(codePostalEtablissementPrecTextField)
				.addComponent(telEtablissementPrecTextField));
		gl.setHorizontalGroup(hGroup);

		// Groupe sequentiel sur l'axe vertical
		GroupLayout.SequentialGroup vGroup = gl.createSequentialGroup();

		// Constitution des groupes paralleles verticalement
		/* 1e ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(etablissementPrecLabel));
		/* 2e ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(etablissementsComboBox)
				.addComponent(ajouterEtablissementPrecButton)
				.addComponent(editerEtablissementPrecButton));
		/* 3e ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(nomEtablissementPrecLabel)
				.addComponent(nomEtablissementPrecTextField)
				.addComponent(rueEtablissementPrecLabel)
				.addComponent(rueEtablissementPrecTextField));
		/* 4e ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(villeEtablissementPrecLabel)
				.addComponent(villeEtablissementPrecTextField)
				.addComponent(codePostalEtablissementPrecLabel)
				.addComponent(codePostalEtablissementPrecTextField));
		/* 5e ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(paysEtablissementPrecLabel)
				.addComponent(paysEtablissementPrecComboBox)
				.addComponent(telEtablissementPrecLabel)
				.addComponent(telEtablissementPrecTextField));
		gl.setVerticalGroup(vGroup);

	}

	private void remplirElevePanel() {
		elevePanel = new JPanel();
		elevePanel.setLayout(new BoxLayout(elevePanel, BoxLayout.PAGE_AXIS));
		elevePanel.add(infosElevePanel);
		elevePanel.add(etablissementPrecPanel);
		elevePanel.add(responsablesClassePanel);
		elevePanel.add(dossierMedicalPanel);
		elevePanel.setBorder(BorderFactory.createTitledBorder("Eleve"));
	}

	private void remplirInfoElevePanel() {
		infosElevePanel = new JPanel();
		GroupLayout gl = new GroupLayout(infosElevePanel);
		infosElevePanel.setLayout(gl);
		// Espacement des composants
		gl.setAutoCreateGaps(true);
		// Espacement entre composants et conteneur
		gl.setAutoCreateContainerGaps(true);

		// Groupe sequentiel sur l'axe horizontal
		GroupLayout.SequentialGroup hGroup = gl.createSequentialGroup();

		// Constitution des groupes paralleles horizontalement
		/* 1e colonne */
		hGroup.addGroup(gl.createParallelGroup().addComponent(sexeMRadioButton)
				.addComponent(prenomEleveLabel)
				.addComponent(dateInscriptionEleveLabel)
				.addComponent(lieuNaissanceEleveLabel)
				.addComponent(dateNaissanceEleveLabel)
				.addComponent(codePostalNaissanceEleveLabel)
				.addComponent(coordonneesEleveLabel)
				.addComponent(rueEleveLabel).addComponent(codePostalEleveLabel)
				.addComponent(emailEleveLabel)
				.addComponent(telMobileEleve1Label));
		/* 2e colonne */
		hGroup.addGroup(gl.createParallelGroup().addComponent(sexeFRadioButton)
				.addComponent(prenomEleveTextField)
				.addComponent(dateInscriptionEleveTextField)
				.addComponent(dateNaissanceEleveTextField)
				.addComponent(codePostalNaissanceEleveTextField)
				.addComponent(rueEleveTextField)
				.addComponent(codePostalEleveTextField)
				.addComponent(emailEleveTextField)
				.addComponent(telMobileEleve1TextField));
		/* 3e colonne */
		hGroup.addGroup(gl.createParallelGroup()
				.addComponent(nationaliteEleveLabel)
				.addComponent(nomEleveLabel).addComponent(matriculeEleveLabel)
				.addComponent(villeNaissanceEleveLabel)
				.addComponent(paysNaissanceEleveLabel)
				.addComponent(villeEleveLabel).addComponent(paysEleveLabel)
				.addComponent(telFixeEleveLabel)
				.addComponent(telMobileEleve2Label));
		/* 4e colonne */
		hGroup.addGroup(gl.createParallelGroup()
				.addComponent(nationaliteEleveComboBox)
				.addComponent(nomEleveTextField)
				.addComponent(matriculeEleveTextField)
				.addComponent(villeNaissanceEleveTextField)
				.addComponent(paysNaissanceEleveComboBox)
				.addComponent(villeEleveTextField)
				.addComponent(paysEleveComboBox)
				.addComponent(telFixeEleveTextField)
				.addComponent(telMobileEleve2TextField));
		/* 5e colonne */
		hGroup.addGroup(gl.createParallelGroup().addComponent(photoEleveLabel));
		/* 6e colonne */
		hGroup.addGroup(gl.createParallelGroup().addComponent(
				photoEleveTextField));
		gl.setHorizontalGroup(hGroup);

		// Groupe sequentiel sur l'axe vertical
		GroupLayout.SequentialGroup vGroup = gl.createSequentialGroup();

		// Constitution des groupes paralleles verticalement
		/* 1e ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(sexeMRadioButton).addComponent(sexeFRadioButton)
				.addComponent(nationaliteEleveLabel)
				.addComponent(nationaliteEleveComboBox));
		/* 2e ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(prenomEleveLabel)
				.addComponent(prenomEleveTextField).addComponent(nomEleveLabel)
				.addComponent(nomEleveTextField));
		/* 3e ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(dateInscriptionEleveLabel)
				.addComponent(dateInscriptionEleveTextField)
				.addComponent(matriculeEleveLabel)
				.addComponent(matriculeEleveTextField)
				.addComponent(photoEleveLabel)
				.addComponent(photoEleveTextField));
		/* 4e ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(lieuNaissanceEleveLabel));
		/* 5e ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(dateNaissanceEleveLabel)
				.addComponent(dateNaissanceEleveTextField)
				.addComponent(villeNaissanceEleveLabel)
				.addComponent(villeNaissanceEleveTextField));
		/* 6e ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(codePostalNaissanceEleveLabel)
				.addComponent(codePostalNaissanceEleveTextField)
				.addComponent(paysNaissanceEleveLabel)
				.addComponent(paysNaissanceEleveComboBox).addGap(50));
		/* 7e ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE).addGap(30)
				.addComponent(coordonneesEleveLabel));
		/* 8e ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(rueEleveLabel).addComponent(rueEleveTextField)
				.addComponent(villeEleveLabel)
				.addComponent(villeEleveTextField));
		/* 9e ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(codePostalEleveLabel)
				.addComponent(codePostalEleveTextField)
				.addComponent(paysEleveLabel).addComponent(paysEleveComboBox));
		/* 10e ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(emailEleveLabel)
				.addComponent(emailEleveTextField)
				.addComponent(telFixeEleveLabel)
				.addComponent(telFixeEleveTextField));
		/* 11e ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(telMobileEleve1Label)
				.addComponent(telMobileEleve1TextField)
				.addComponent(telMobileEleve2Label)
				.addComponent(telMobileEleve2TextField));
		gl.setVerticalGroup(vGroup);
	}

	private void remplirMedecinPanel() {
		medecinPanel = new JPanel();
		GroupLayout gl = new GroupLayout(medecinPanel);
		medecinPanel.setLayout(gl);
		// Espacement des composants
		gl.setAutoCreateGaps(true);
		// Espacement entre composants et conteneur
		gl.setAutoCreateContainerGaps(true);

		// Groupe sequentiel sur l'axe horizontal
		GroupLayout.SequentialGroup hGroup = gl.createSequentialGroup();

		/* 1e colonne */
		hGroup.addGroup(gl.createParallelGroup()
				.addComponent(prenomMedecinLabel)
				.addComponent(telephoneMedecinLabel)
				.addComponent(rueMedecinLabel)
				.addComponent(codePostalMedecinLabel));
		/* 2e colonne */
		hGroup.addGroup(gl.createParallelGroup()
				.addComponent(medecinsTraitantComboBox)
				.addComponent(prenomMedecinTextField)
				.addComponent(telephoneMedecinTextField)
				.addComponent(rueMedecinTextField)
				.addComponent(codePostalMedecinTextField));
		/* 3e colonne */
		hGroup.addGroup(gl.createParallelGroup()
				.addComponent(ajouterMedecinButton)
				.addComponent(nomMedecinLabel).addComponent(emailMedecinLabel)
				.addComponent(villeMedecinLabel).addComponent(paysMedecinLabel));
		/* 4e colonne */
		hGroup.addGroup(gl.createParallelGroup()
				.addComponent(editerMedecinButton)
				.addComponent(nomMedecinTextField)
				.addComponent(emailMedecinTextField)
				.addComponent(villeMedecinTextField)
				.addComponent(paysMedecinComboBox));
		gl.setHorizontalGroup(hGroup);

		// Groupe sequentiel sur l'axe vertical
		GroupLayout.SequentialGroup vGroup = gl.createSequentialGroup();

		/* 1e ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(medecinsTraitantComboBox)
				.addComponent(ajouterMedecinButton)
				.addComponent(editerMedecinButton));
		/* 2e ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(prenomMedecinLabel)
				.addComponent(prenomMedecinTextField)
				.addComponent(nomMedecinLabel)
				.addComponent(nomMedecinTextField));
		/* 3e ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(telephoneMedecinLabel)
				.addComponent(telephoneMedecinTextField)
				.addComponent(emailMedecinLabel)
				.addComponent(emailMedecinTextField));
		/* 4e ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(rueMedecinLabel)
				.addComponent(rueMedecinTextField)
				.addComponent(villeMedecinLabel)
				.addComponent(villeMedecinTextField));
		/* 5e ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(codePostalMedecinLabel)
				.addComponent(codePostalMedecinTextField)
				.addComponent(paysMedecinLabel)
				.addComponent(paysMedecinComboBox));
		gl.setVerticalGroup(vGroup);
		medecinPanel.setBorder(BorderFactory
				.createTitledBorder("Médecin traitant"));
	}

	private void remplirResponsablesClassePanel() {
		responsablesClassePanel = new JPanel();
		GroupLayout gl = new GroupLayout(responsablesClassePanel);
		responsablesClassePanel.setLayout(gl);
		// Espacement des composants
		gl.setAutoCreateGaps(true);
		// Espacement entre composants et conteneur
		gl.setAutoCreateContainerGaps(true);

		// Groupe sequentiel sur l'axe horizontal
		GroupLayout.SequentialGroup hGroup = gl.createSequentialGroup();

		// Constitution des groupes paralleles horizontalement
		/* Premiere colonne */
		hGroup.addGroup(gl.createParallelGroup()
				.addComponent(responsablesComboBox)
				.addComponent(classesComboBox));
		/* Deuxieme colonne */
		hGroup.addGroup(gl.createParallelGroup().addComponent(
				ajouterResponsableButton));
		/* Troisieme colonne */
		hGroup.addGroup(gl.createParallelGroup().addComponent(
				editerResponsableButton));
		/* Troisieme colonne */
		hGroup.addGroup(gl.createParallelGroup().addComponent(
				supprimerResponsableButton));
		gl.setHorizontalGroup(hGroup);

		// Groupe sequentiel sur l'axe vertical
		GroupLayout.SequentialGroup vGroup = gl.createSequentialGroup();

		// Constitution des groupes paralleles verticalement
		/* Premiere ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(responsablesComboBox)
				.addComponent(ajouterResponsableButton)
				.addComponent(editerResponsableButton)
				.addComponent(supprimerResponsableButton));
		/* Deuxieme ligne */
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(classesComboBox));
		gl.setVerticalGroup(vGroup);

	}

	private void remplirDossierMedicalPanel() {
		dossierMedicalPanel = new JPanel();
		GroupLayout gl = new GroupLayout(dossierMedicalPanel);
		dossierMedicalPanel.setLayout(gl);
		// Espacement des composants
		gl.setAutoCreateGaps(true);
		// Espacement entre composants et conteneur
		gl.setAutoCreateContainerGaps(true);

		// Groupe sequentiel sur l'axe horizontal
		GroupLayout.SequentialGroup hGroup = gl.createSequentialGroup();

		// Constitution des groupes paralleles horizontalement
		hGroup.addGroup(gl.createParallelGroup().addComponent(allergiesLabel)
				.addComponent(vaccinsLabel).addComponent(rmqMedicalesLabel));
		hGroup.addGroup(gl.createParallelGroup()
				.addComponent(allergiesTextArea).addComponent(vaccinsTextArea)
				.addComponent(rmqMedicalesTextArea));
		gl.setHorizontalGroup(hGroup);

		// Groupe sequentiel sur l'axe vertical
		GroupLayout.SequentialGroup vGroup = gl.createSequentialGroup();

		// Constitution des groupes paralleles verticalement
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(allergiesLabel).addComponent(allergiesTextArea));
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(vaccinsLabel).addComponent(vaccinsTextArea));
		vGroup.addGroup(gl.createParallelGroup(Alignment.BASELINE)
				.addComponent(rmqMedicalesLabel)
				.addComponent(rmqMedicalesTextArea));
		gl.setVerticalGroup(vGroup);

	}

	private void remplirValidationPanel() {
		validationPanel = new JPanel();
		validationPanel.add(ajouterEleveButton);
	}

	private void remplirNorthPanel() {
		northPanel = new JPanel();
		northPanel.add(titleLabel);
	}

	private void remplirMainPanel() {
		GroupLayout gl = new GroupLayout(mainPanel);
		mainPanel.setLayout(gl);
		// Espacement des composants
		gl.setAutoCreateGaps(true);
		// Espacement entre composants et conteneur
		gl.setAutoCreateContainerGaps(true);

		// Groupe sequentiel pour l'axe horizontal
		GroupLayout.SequentialGroup hGroup = gl.createSequentialGroup();
		hGroup.addGroup(gl.createParallelGroup().addComponent(elevePanel)
				.addComponent(medecinPanel).addComponent(validationPanel));
		gl.setHorizontalGroup(hGroup);

		// Groupe sequentiel pour l'axe vertical
		GroupLayout.SequentialGroup vGroup = gl.createSequentialGroup();
		vGroup.addGroup(gl.createParallelGroup().addComponent(elevePanel));
		vGroup.addGroup(gl.createParallelGroup().addComponent(medecinPanel));
		vGroup.addGroup(gl.createParallelGroup().addComponent(validationPanel));
		gl.setVerticalGroup(vGroup);
		mainPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
	}

	/**
	 * Reinitialiser la combobox des responsables grâce au controleur
	 */
	private void updateResponsableCombobox() {
		responsablesComboBox.removeAllItems();
		responsablesComboBox.addItem("--Editer/Supprimer un responsable--");
		try {
			for (Responsable responsable : controleur.getResponsables()) {
				responsablesComboBox.addItem(responsable);
			}
		} catch (HibernateException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		// Remise à l'index zero de la combobox
		responsablesComboBox.setSelectedIndex(0);
	}

	public abstract String getTitle();

	public abstract String getEditionBoutonText();

	/* Listeners */
	class EditerEleveButtonListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			String title = "Renseignement(s) manquant(s)";

			int indexNationalitePays = nationaliteEleveComboBox
					.getSelectedIndex();
			int indexPaysNaissance = paysNaissanceEleveComboBox
					.getSelectedIndex();
			int indexPaysEleve = paysEleveComboBox.getSelectedIndex();
			int indexMedecin = medecinsTraitantComboBox.getSelectedIndex();
			int indexClasse = classesComboBox.getSelectedIndex();
			int indexEtablissementPrecedent = etablissementsComboBox
					.getSelectedIndex();
			int nbResponsables = responsablesComboBox.getItemCount();
			if (!verifComboBoxIndexOK(indexNationalitePays)) {
				Tools.displayError("Nationalité non renseignée", title);
			} else if (!verifComboBoxIndexOK(indexPaysNaissance)) {
				Tools.displayError("Pays naissance non renseigné", title);
			} else if (!verifComboBoxIndexOK(indexPaysEleve)) {
				Tools.displayError("Pays de résidence non renseigné", title);
			} else if (!verifComboBoxIndexOK(indexMedecin)) {
				Tools.displayError("Medecin inconnu", title);
			} else if (!(sexeFRadioButton.isSelected() || sexeMRadioButton
					.isSelected())) {
				Tools.displayError("Sexe non renseigné", title);
			} else if (responsablesComboBox.getItemCount() < 1) {
				// Au moins un responsable
				Tools.displayError("Responsable(s) manquant", title);
			} else if (!verifComboBoxIndexOK(indexClasse)) {
				Tools.displayError("Classe courante manquante", title);
			} else if (!verifComboBoxIndexOK(indexEtablissementPrecedent)) {
				Tools.displayError("Etablissement precedent manquant", title);
			} else if (nbResponsables < 1) {
				Tools.displayError("Des responsables sont requis", title);
			} else {
				// Tout est valide
				final Pays nationaliteEleve = controleur.getPays().get(
						indexNationalitePays - 1);
				final Pays paysNaissance = controleur.getPays().get(
						indexPaysNaissance - 1);
				final Pays paysEleve = controleur.getPays().get(
						indexPaysEleve - 1);
				final String sexe = sexeFRadioButton.isSelected() ? Eleve.FEMME
						: Eleve.HOMME;
				final Etablissement etablissementPrecedent = (Etablissement) etablissementsComboBox
						.getSelectedItem();
				final Medecin medecinTraitant = (Medecin) medecinsTraitantComboBox
						.getSelectedItem();
				final Classe classeCourante = (Classe) classesComboBox
						.getSelectedItem();

				// Lancement de la sauvegarde
				// pendant ce temps, chargement
				boolean valid = false;
				try {
					controleur.setClasseCourante(classeCourante);
					controleur.editEleve(matriculeEleveTextField.getText(),
							nomEleveTextField.getText(),
							prenomEleveTextField.getText(),
							dateNaissanceEleveTextField.getText(),
							codePostalNaissanceEleveTextField.getText(),
							villeNaissanceEleveTextField.getText(),
							paysNaissance, nationaliteEleve, sexe,
							rueEleveTextField.getText(),
							codePostalEleveTextField.getText(),
							villeEleveTextField.getText(), paysEleve,
							emailEleveTextField.getText(),
							dateInscriptionEleveTextField.getText(),
							etablissementPrecedent,
							photoEleveTextField.getText(),
							telFixeEleveTextField.getText(),
							telMobileEleve1TextField.getText(),
							telMobileEleve2TextField.getText(),
							medecinTraitant, rmqMedicalesTextArea.getText(),
							vaccinsTextArea.getText(),
							allergiesTextArea.getText());
					valid = true;
				} catch (LogicException ex) {
					Tools.displayError(ex.getMessage(),
							"Erreur durant sauvegarde");
				}
				// Lancement de la validation
				if (valid)
					new Thread(new ControlerValidator(controleur, vueParente))
							.start();
				vueParente.startBarreChargement();
			}
		}

		private boolean verifComboBoxIndexOK(int index) {
			return index > 0;
		}
	}

	class AjouterResponsableButtonListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			// Recherche d'un eleve
			new VueAjouterResponsable(vueParente, controleur);
			updateResponsableCombobox();
		}
	}

	class EditerResponsableButtonListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			// Action uniquement si on a choisi un index correspondant à un
			// responsable
			if (responsablesComboBox.getSelectedIndex() != 0) {
				Responsable responsable = (Responsable) responsablesComboBox
						.getSelectedItem();
				// Recherche d'un eleve
				new VueEditerResponsable(vueParente, controleur, responsable);

				updateResponsableCombobox();
			}
		}
	}

	class SupprimerResponsableButtonListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			// Action uniquement si on a choisi un index correspondant à un
			// responsable
			if (responsablesComboBox.getSelectedIndex() != 0) {
				Responsable responsable = (Responsable) responsablesComboBox
						.getSelectedItem();
				// Suppression
				try {
					controleur.removeResponsable(responsable);
					// Suppression dans la combobox
					updateResponsableCombobox();
				} catch (LogicException e1) {
					// Afficher l'erreur a l'utilisateur
					Tools.displayError(e1.getMessage(),
							"destruction du responsable impossible");
				} catch (Exception e2) {
					e2.printStackTrace();
				}
			}
		}
	}

	class EditerMedecinButtonListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			// Seul un medecin de la liste peut etre edite
			if (medecinsTraitantComboBox.getSelectedIndex() != 0) {
				if (infoMedecinVisible) {
					boolean ckecks = true;
					// Mis à jour du medecin apres verification des
					// champs
					if (infoMedecinEnabled
							&& paysMedecinComboBox.getSelectedIndex() != 0) {
						ckecks = false;
						try {
							controleur.editMedecin(
									(Medecin) medecinsTraitantComboBox
											.getSelectedItem(),
									nomMedecinTextField.getText(),
									prenomMedecinTextField.getText(),
									telephoneMedecinTextField.getText(),
									emailMedecinTextField.getText(),
									rueMedecinTextField.getText(),
									codePostalMedecinTextField.getText(),
									villeMedecinTextField.getText(),
									(Pays) paysMedecinComboBox
											.getSelectedItem());
							ckecks = true;
						} catch (LogicException e1) {
							Tools.displayError(e1.getMessage(),
									"Edition medecin");
						} catch (Exception e2) {
							e2.printStackTrace();
							System.err
									.println("Exception inconnue dans editMedecin");
						}
					}
					// Griser/Degriser les informations du medecin
					if (ckecks)
						afficherInfosMedecins(true, !infoMedecinEnabled);
				} else {
					// Afficher et degriser les infos du medecin
					afficherInfosMedecins(true, true);
				}
			}

			// Griser/Degriser le bouton d'ajout en fonction de l'etat d'edition
			if (!editerMedecinInProgress)
				ajouterMedecinButton.setEnabled(false);
			else
				ajouterMedecinButton.setEnabled(true);
			// Activer/Terminer l'edition
			editerMedecinInProgress = !editerMedecinInProgress;

		}
	}

	class AjouterMedecinButtonListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			if (infoMedecinVisible) {
				// Ajout du medecin apres verification des champs
				if (infoMedecinEnabled) {
					boolean dataCkecks = false;
					try {
						if (paysMedecinComboBox.getSelectedIndex() == 0)
							throw new LogicException("Pays invalide");
						Pays pays = (Pays) paysMedecinComboBox
								.getSelectedItem();
						Medecin medecin = controleur.ajoutMedecin(
								nomMedecinTextField.getText(),
								prenomMedecinTextField.getText(),
								telephoneMedecinTextField.getText(),
								emailMedecinTextField.getText(),
								rueMedecinTextField.getText(),
								codePostalMedecinTextField.getText(),
								villeMedecinTextField.getText(), pays);
						medecinsTraitantComboBox.addItem(medecin);
						dataCkecks = true;
					} catch (LogicException e1) {
						Tools.displayError(e1.getMessage(), "Ajout medecin");
					} catch (Exception e2) {
						e2.printStackTrace();
						System.err
								.println("Exception inconnue dans ajoutMedecin");
					}

					if (dataCkecks) {
						resetInfoMedecin();
						medecinsTraitantComboBox.setSelectedIndex(0);
						afficherInfosMedecins(false, false);
					}
				} else {
					editerMedecinButton.setEnabled(false);
					resetInfoMedecin();
					afficherInfosMedecins(true, true);
				}
			} else {
				medecinsTraitantComboBox.setSelectedIndex(0);
				afficherInfosMedecins(true, true);
			}
		}

	}

	class EditerEtablissementPrecButtonListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			// Seul un etablissement de la liste peut etre edite
			if (etablissementsComboBox.getSelectedIndex() != 0) {
				if (infoEtablissementVisible) {
					// Mise à jour de l'etablissement
					boolean actionValide = false;
					if (infoEtablissementEnabled) {
						try {
							Etablissement etablissement = (Etablissement) etablissementsComboBox
									.getSelectedItem();
							if (paysEtablissementPrecComboBox
									.getSelectedIndex() == 0)
								throw new LogicException("Pays invalide");
							Pays pays = (Pays) paysEtablissementPrecComboBox
									.getSelectedItem();
							controleur.editEtablissement(etablissement,
									nomEtablissementPrecTextField.getText(),
									rueEtablissementPrecTextField.getText(),
									codePostalEtablissementPrecTextField
											.getText(),
									nomEtablissementPrecTextField.getText(),
									pays, telEtablissementPrecTextField
											.getText());
							actionValide = true;
						} catch (LogicException e1) {
							Tools.displayError(e1.getMessage(),
									"Editer etablissement");
						} catch (Exception e2) {
							e2.printStackTrace();
							System.err
									.println("Erreur inconnue dans EditerEtablissementPrecButtonListener");
						}
						// Griser les champs a la fin
						if (actionValide) {
							afficherInfosEtablissements(true,
									!editerEtablissementInProgress);
						}
					} else {
						// Afficher et degriser les infos de l'etablissement
						afficherInfosEtablissements(true, true);
					}
				}
			}

			// Griser/Degriser le bouton d'ajout en fonction de l'etat d'edition
			if (editerEtablissementInProgress)
				ajouterEtablissementPrecButton.setEnabled(true);
			else
				ajouterEtablissementPrecButton.setEnabled(false);
			// Activer/Terminer l'edition
			editerEtablissementInProgress = !editerEtablissementInProgress;
		}
	}

	class AjouterEtablissementPrecButtonListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			if (infoEtablissementVisible) {
				// Ajout de l'etablissement apres verification des champs
				if (infoEtablissementEnabled) {
					boolean actionValide = false;
					try {
						if (paysEtablissementPrecComboBox.getSelectedIndex() == 0)
							throw new LogicException("Pays invalide");
						Pays pays = (Pays) paysEtablissementPrecComboBox
								.getSelectedItem();
						// Creation et ajout à la combobox
						Etablissement etablissement = controleur
								.ajoutEtablissement(
										nomEtablissementPrecTextField.getText(),
										rueEtablissementPrecTextField.getText(),
										codePostalEtablissementPrecTextField
												.getText(),
										nomEtablissementPrecTextField.getText(),
										pays, telEtablissementPrecTextField
												.getText());
						etablissementsComboBox.addItem(etablissement);
						actionValide = true;
					} catch (LogicException e1) {
						Tools.displayError(e1.getMessage(),
								"Editer etablissement");
					} catch (Exception e2) {
						e2.printStackTrace();
						System.err
								.println("Erreur inconnue dans EditerEtablissementPrecButtonListener");
					}
					if (actionValide) {
						etablissementsComboBox.setSelectedIndex(0);
						resetInfoEtablissement();
						afficherInfosEtablissements(false, false);
					}
				} else {
					// Editer devient indisponible et champs à ""
					editerEtablissementPrecButton.setEnabled(false);
					resetInfoEtablissement();
					afficherInfosEtablissements(true, true);
				}
			} else {
				etablissementsComboBox.setSelectedIndex(0);
				afficherInfosEtablissements(true, true);
			}
		}

	}

	class MedecinsTraitantComboBoxListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			JComboBox cb = (JComboBox) e.getSource();
			// On viens de changer de medecin, donc l'edition est suspendue
			editerMedecinInProgress = false;
			// Autoriser l'ajout de medecin
			ajouterMedecinButton.setEnabled(true);
			// Si on selectionne l'entete
			if (cb.getSelectedIndex() == 0) {
				// Reinitialiser les champs
				resetInfoMedecin();
				// Desactiver l'edition
				editerMedecinButton.setEnabled(false);
				// Masquer les infos d'un medecin
				afficherInfosMedecins(false, false);
			} else {
				// Activer l'edition
				editerMedecinButton.setEnabled(true);
				Medecin medecin = (Medecin) cb.getSelectedItem();
				nomMedecinTextField.setText(medecin.getNom());
				prenomMedecinTextField.setText(medecin.getPrenom());
				telephoneMedecinTextField.setText(medecin.getTelephoneFixe());
				emailMedecinTextField.setText(medecin.getEmail());
				rueMedecinTextField.setText(medecin.getRue());
				Ville villeMedecin = medecin.getVille();
				villeMedecinTextField.setText(villeMedecin.getNom());
				codePostalMedecinTextField
						.setText(villeMedecin.getCodePostal());
				paysMedecinComboBox.setSelectedItem(villeMedecin.getPays());
				afficherInfosMedecins(true, false);
			}

		}
	}

	class EtablissementsComboBoxListener implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			JComboBox cb = (JComboBox) e.getSource();
			// On viens de changer d'etablissement, donc l'edition est suspendue
			editerEtablissementInProgress = false;
			// Autoriser l'ajout d'etablissement
			ajouterEtablissementPrecButton.setEnabled(true);
			// Si on selectionne l'entete
			if (cb.getSelectedIndex() == 0) {
				// Reinitialiser les champs
				resetInfoEtablissement();
				// Desactiver l'edition
				editerEtablissementPrecButton.setEnabled(false);
				// Masquer les infos d'un etablissement
				afficherInfosEtablissements(false, false);
			} else {
				// Activer l'edition
				editerEtablissementPrecButton.setEnabled(true);
				Etablissement etablissementPrec = (Etablissement) cb
						.getSelectedItem();
				nomEtablissementPrecTextField.setText(etablissementPrec
						.getNom());
				rueEtablissementPrecTextField.setText(etablissementPrec
						.getRue());
				Ville villeEtablissementPrec = etablissementPrec.getVille();
				villeEtablissementPrecTextField.setText(villeEtablissementPrec
						.getNom());
				codePostalEtablissementPrecTextField
						.setText(villeEtablissementPrec.getCodePostal());
				paysEtablissementPrecComboBox
						.setSelectedItem(villeEtablissementPrec.getPays());
				afficherInfosEtablissements(true, false);
			}
		}
	}
}
